
// amb diferents parÃ metres
assert.equals(2, lambda("2")());
assert.equals(2, lambda("=> 2")());
assert.equals(6, lambda("x => x*2")(3));
assert.equals(5, lambda("x,y => x+y")(2,3));
assert.equals(6, lambda("x,y => x*y")(2,3));

// currys
assert.equals(2*3, lambda("x => y => x*y")(2)(3));
assert.equals(2*3*4, lambda("x => y => z => x*y*z")(2)(3)(4));
assert.equals(2+3+4, lambda("x => y,z => x+y+z")(2)(3,4));
assert.equals(1+2+3+4+5+6, lambda("a,b => c => d,e => f => a+b+c+d+e+f")(1,2)(3)(4,5)(6));

// test d'expressions pre-compilades

var c = "x => x*2";
var cc = lambda(c);
assert.equals(6, lambda(c)(3));
assert.equals(6, lambda(cc)(3));


// contra propietats de bean
var m = {
	name : "mhc",
	age : 28
};
assert.equals("mhc", lambda("o => o.name")(m));
assert.equals(28, lambda("o => o.age")(m));

var m = {
	first : {
		name : "mhc",
		age : 28
	},
	second : {
		name : "arb",
		age : 26
	}
};
assert.equals("mhc", lambda("o => o.first.name")(m));
assert.equals(28, lambda("o => o.first.age")(m));
assert.equals("arb", lambda("o => o.second.name")(m));
assert.equals(26, lambda("o => o.second.age")(m));



// demostraciÃ³ d'expressiÃ³ factorial amb <tt>arguments.callee(...)</tt>
var fact = function(n) {
	return n <= 1 ? 1 : n * fact(n - 1);
};
assert.sequals(120, fact(5));

var fact = lambda("n => n <= 1 ? 1 : n * arguments.callee(n - 1)");
assert.sequals(120, fact(5));


var fact = lambda("n => n <= 1 ? 1 : n * @(n - 1)");
assert.sequals(120, fact(5));

println(fact);

//

//







assert.equals(10, fold("a,v => a + v", 0, [ 1, 2, 3, 4 ]));
assert.equals(24, fold("a,v => a * v", 1, [ 1, 2, 3, 4 ]));
assert.equals(6, fold("a,v => a * v", 1, { "a":1, "b":2, "c":3 }));

assert.equals("0123", foldKeys("a,v => a + v", "", [ 1, 2, 3, 4 ]));
assert.equals("abc", foldKeys("a,v => a+v", "", { "a":1, "b":2, "c":3 }));















assert.equals( [ 2, 4, 6 ], map("x => x*2", [ 1, 2, 3 ]));
assert.equals( [ 1, 4, 9 ], map("x => x*x", [ 1, 2, 3 ]));
assert.equals( { "o":2, "t":4, "t3":6 }, map("x => x*2", { "o":1, "t":2, "t3":3 }));
assert.equals( {3:2,6:4,9:6}, mapKeys("x => x*3", {1:2,2:4,3:6}));

assert.equals( [ 1, "x", 3, "x", 5], map("x => x%2==0?'x':x", [ 1, 2, 3, 4, 5 ]));


// function extract(collection, property) {
// var r = newCollection(collection);
// for (e in collection) {
// r[e] = collection[e][property];
// }
// return r;
// };

var beans = [ {
	name : "arb",
	age : 25
}, {
	name : "mhc",
	age : 28
} ];

// assert.equals( [ "arb", "mhc" ], extract(beans, "name"));
// assert.equals( [ 25, 28 ], extract(beans, "age"));
assert.equals( [ "arb", "mhc" ], map("x => x.name", beans));
assert.equals( [ 25, 28 ], map("x=>x.age", beans));














assert.equals([2, 4], selectIf("x => x % 2 == 0", [1,2,3,4,5]));
assert.equals({"b":2}, selectIf("x => x % 2 == 0", { "a":1, "b":2, "c":3 }));

assert.equals([1, 3, 5], removeIf("x => x % 2 == 0", [1,2,3,4,5]));
assert.equals({"a":1,"c":3}, removeIf("x => x % 2 == 0", { "a":1, "b":2, "c":3 }));


assert.equals([1,3,5], selectIfKey("x => x % 2 == 0", [1,2,3,4,5]));
assert.equals({"b":2}, selectIfKey("x => x == 'b'", { "a":1, "b":2, "c":3 }));

assert.equals([2,4], removeIfKey("x => x % 2 == 0", [1,2,3,4,5]));
assert.equals({"a":1,"c":3}, removeIfKey("x => x == 'b'", { "a":1, "b":2, "c":3 }));












assert.equals( {"mhc":{"age":28,"name":"mhc"},"arb":{"age":25,"name":"arb"}}, enMap("x => x.name", beans));


//function doc(lambdaExp, invocation) {
//	println("<tt>" + lambdaExp + "</tt> produces: ");
//	print("<pre>");
//	print(eval(lambdaExp));
//	println("</pre>");
//	print(", calling <tt>" + lambdaExp + invocation +"</tt>");
//	print(" produces: <b>" + eval(lambdaExp + invocation) + "</b>");
//	println("<br/>");
//	println("");
//
//
//	println("");
//}
//
//
//doc('lambda("2")', "()");
//doc('lambda("=> 3")', "()");
//doc('lambda("x => 4")', "(5)");
//doc('lambda("x => x")', "(6)");
//doc('lambda("x,y => x*y")', "(2,3)");
//doc('lambda("x,y => z => (x+y)*z")', "(2,3)(4)");
//doc('lambda("a => x,y => z => a+x+y+z")', "(1)(2,3)(4)");


/*
 * càlcul de primos
 */

function seq(start, end) {
	var r = [];
	for (i = start; i <= end; i++) {
		r.push(i);
	}
	return r;
}

assert.equals([2,3,4,5,6,7,8,9,10], seq(2,10));


function primos(max) {
	var primos = seq(2, max);
	for (i = 2; i <= max; i++) {
		primos = removeIf("x => x!=i && x%i==0", primos);
	}
	return primos;
}

assert.sequals([2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97], primos(100));

















var S = new Generator("x;[0,1,2,3,4,5];x*2;x%3==0");
assert.sequals(0, S.next());
assert.sequals(6, S.next());
assert.isUndefined(S.next());

var A = [0,1,2,3,4,5];
var S = new Generator("x;A;x*2;x%3==0");
assert.sequals(0, S.next());
assert.sequals(6, S.next());
assert.isUndefined(S.next());

var S = new Generator("x;range(0,5);x*2;x%3==0");
assert.sequals(0, S.next());
assert.sequals(6, S.next());
assert.isUndefined(S.next());


var S = new Generator("x;range(0,3);x*2");
assert.sequals(0, S.next());
assert.sequals(2, S.next());
assert.sequals(4, S.next());
assert.sequals(6, S.next());
assert.isUndefined(S.next());

var S = new Generator("x;range(0,3)");
assert.sequals(0, S.next());
assert.sequals(1, S.next());
assert.sequals(2, S.next());
assert.sequals(3, S.next());
assert.isUndefined(S.next());

var S = new Generator("x;range(0,3);;x%2==1");
assert.sequals(1, S.next());
assert.sequals(3, S.next());
assert.isUndefined(S.next());






assert.sequals([0,6], listOf("x;[0,1,2,3,4,5];x*2;x%3==0"));
assert.sequals([0,6], listOf("x;A;x*2;x%3==0"));
assert.sequals([0,6], listOf("x;range(0,5);x*2;x%3==0"));

assert.sequals([0,2,4,6], listOf("x;range(0,3);x*2"));
assert.sequals([0,1,2,3], listOf("x;range(0,3)"));
assert.sequals([1,3], listOf("x;range(0,3);;x%2==1"));



